package com.imedway.ihe.dtz.xds.registry.camel;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLObjectLibrary;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLRegistryError;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.EbXMLQueryResponse30;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.EbXMLRegistryError30;
import org.openehealth.ipf.commons.ihe.xds.core.requests.QueryRegistry;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindDocumentsByReferenceIdQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindDocumentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindFoldersQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindSubmissionSetsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetAllQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetAssociationsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetDocumentsAndAssociationsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetDocumentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetFolderAndContentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetFoldersForDocumentQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetFoldersQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetRelatedDocumentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetSubmissionSetAndContentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetSubmissionSetsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.QueryType;
import org.openehealth.ipf.commons.ihe.xds.core.responses.ErrorCode;
import org.openehealth.ipf.commons.ihe.xds.core.responses.QueryResponse;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Severity;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Status;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.query.AdhocQueryRequest;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.query.AdhocQueryResponse;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs.RegistryError;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs.RegistryErrorList;
import org.openehealth.ipf.platform.camel.ihe.xds.core.converters.EbXML30Converters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import com.imedway.ihe.dtz.xds.dao.DataDao;
import com.imedway.ihe.dtz.xds.dao.camel.Iti18Dao_CAMEL;
import com.imedway.ihe.dtz.xds.dto.XdsDto;
import com.imedway.ihe.dtz.xds.entity.IheXdsFileInfo;

import lombok.extern.slf4j.Slf4j;

/**
 * @author dtz<br/>
 * @date 2024/7/25
 */
@Slf4j
@Configuration
public class Iti18Registry_CAMEL {
	
	@Autowired
	private Iti18Dao_CAMEL iti18Dao_CAMEL;
	
	public AdhocQueryResponse run(AdhocQueryRequest body) {
//		EbXMLAdhocQueryRequest30 ebXMLBody= new EbXMLAdhocQueryRequest30(body);	
		AdhocQueryResponse adhocQueryResponse=new AdhocQueryResponse();					
//		adhocQueryResponse.setRegistryObjectList(new RegistryObjectListType());
		EbXMLQueryResponse30 ebXMLQueryResponse30= new EbXMLQueryResponse30(adhocQueryResponse,	new EbXMLObjectLibrary());	
		
		List<EbXMLRegistryError> registryError = new ArrayList<EbXMLRegistryError>();
		boolean flag = true;	
		try {
			QueryRegistry queryRegistry = EbXML30Converters.convert(body);
			QueryType queryType = queryRegistry.getQuery().getType();			
			switch (queryType) {
			case FIND_DOCUMENTS:
				adhocQueryResponse = this.FIND_DOCUMENTS(registryError,queryRegistry);
				break;
			case FIND_SUBMISSION_SETS:
				adhocQueryResponse = this.FIND_SUBMISSION_SETS(registryError,queryRegistry);
				break;
			case FIND_FOLDERS:
				adhocQueryResponse = this.FIND_FOLDERS(registryError,queryRegistry);
				break;
			case GET_ALL:
				adhocQueryResponse = this.GET_ALL(registryError,queryRegistry);
				break;
			case GET_DOCUMENTS:
				adhocQueryResponse = this.GET_DOCUMENTS(registryError,queryRegistry);
				break;
			case GET_FOLDERS:
				adhocQueryResponse = this.GET_FOLDERS(registryError,queryRegistry);
				break;
			case GET_ASSOCIATIONS:
				adhocQueryResponse = this.GET_ASSOCIATIONS(registryError,queryRegistry);
				break;	
			case GET_DOCUMENTS_AND_ASSOCIATIONS:
				adhocQueryResponse = this.GET_DOCUMENTS_AND_ASSOCIATIONS(registryError,queryRegistry);
				break;				
			case GET_SUBMISSION_SETS:
				adhocQueryResponse = this.GET_SUBMISSION_SETS(registryError,queryRegistry);
				break;	
			case GET_FOLDER_AND_CONTENTS:
				adhocQueryResponse = this.GET_FOLDER_AND_CONTENTS(registryError,queryRegistry);
				break;
			case GET_FOLDERS_FOR_DOCUMENT:
				adhocQueryResponse = this.GET_FOLDERS_FOR_DOCUMENT(registryError,queryRegistry);
				break;
			case GET_SUBMISSION_SET_AND_CONTENTS:
				adhocQueryResponse = this.GET_SUBMISSION_SET_AND_CONTENTS(registryError,queryRegistry);
				break;
			case GET_RELATED_DOCUMENTS:
				adhocQueryResponse = this.GET_RELATED_DOCUMENTS(registryError,queryRegistry);
				break;
			case FIND_DOCUMENTS_BY_REFERENCE_ID:
				adhocQueryResponse = this.FIND_DOCUMENTS_BY_REFERENCE_ID(registryError,queryRegistry);
				break;
		    //以上是已经支持的	
			case FIND_DOCUMENTS_MPQ:
				break;
			case FIND_FOLDERS_MPQ:
				break;
			case FETCH:
				break;
			case FIND_MEDICATION_TREATMENT_PLANS:
				break;
			case FIND_PRESCRIPTIONS:
				break;
			case FIND_DISPENSES:
				break;
			case FIND_MEDICATION_ADMINISTRATIONS:
				break;
			case FIND_PRESCRIPTIONS_FOR_VALIDATION:
				break;
			case FIND_PRESCRIPTIONS_FOR_DISPENSE:
				break;
			case FIND_MEDICATION_LIST:
				break;
			case FIND_DOCUMENTS_BY_TITLE:
				break;
			default:
				break;
			}
		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		if(registryError!=null&&registryError.size()>0) {
			flag = false;
			ebXMLQueryResponse30.setErrors(registryError);
		}
		ebXMLQueryResponse30.setStatus(flag ? Status.SUCCESS : Status.FAILURE);
		RegistryErrorList registryErrorList = new RegistryErrorList();
		for(EbXMLRegistryError ebXMLRegistryError:registryError) {
			RegistryError registryErrors = new RegistryError();
			registryErrors.setErrorCode(ebXMLRegistryError.getErrorCode());
			registryErrors.setValue(ebXMLRegistryError.getCodeContext());
			registryErrors.setSeverity(registryErrors.getSeverity());
			registryErrors.setCodeContext(ebXMLRegistryError.getCodeContext());
			registryErrorList.getRegistryError().add(registryErrors);
		}
		if(registryErrorList!=null) {
//			adhocQueryResponse.setRegistryErrorList(registryErrorList);
		}
		adhocQueryResponse.setStatus(flag ? Status.SUCCESS.getOpcode30() : Status.FAILURE.getOpcode30());
//		log.info(JaxbMapperUtils.convertToXml(adhocQueryResponse, "UTF-8", true));

		return adhocQueryResponse;
	}
	
	
	private AdhocQueryResponse FIND_DOCUMENTS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();

		try {
			FindDocumentsQuery findDocumentsQuery =(FindDocumentsQuery)queryRegistry.getQuery();
			QueryResponse queryResponse = iti18Dao_CAMEL.FIND_DOCUMENTS(findDocumentsQuery);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);
			
	
		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;

	}
	
	
	private AdhocQueryResponse FIND_SUBMISSION_SETS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			FindSubmissionSetsQuery query =(FindSubmissionSetsQuery)queryRegistry.getQuery();
			QueryResponse queryResponse = iti18Dao_CAMEL.FIND_SUBMISSION_SETS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);
		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse FIND_FOLDERS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			FindFoldersQuery query =(FindFoldersQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.FIND_FOLDERS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);
		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	
	private AdhocQueryResponse GET_ALL(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetAllQuery query =(GetAllQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_ALL(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_DOCUMENTS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetDocumentsQuery query =(GetDocumentsQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_DOCUMENTS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_FOLDERS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetFoldersQuery query =(GetFoldersQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_FOLDERS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_ASSOCIATIONS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetAssociationsQuery query =(GetAssociationsQuery)queryRegistry.getQuery();	
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_ASSOCIATIONS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);
		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_DOCUMENTS_AND_ASSOCIATIONS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetDocumentsAndAssociationsQuery query =(GetDocumentsAndAssociationsQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_DOCUMENTS_AND_ASSOCIATIONS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);
		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_SUBMISSION_SETS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetSubmissionSetsQuery query =(GetSubmissionSetsQuery)queryRegistry.getQuery();	
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_SUBMISSION_SETS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_FOLDER_AND_CONTENTS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetFolderAndContentsQuery query =(GetFolderAndContentsQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_FOLDER_AND_CONTENTS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	private AdhocQueryResponse GET_FOLDERS_FOR_DOCUMENT(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetFoldersForDocumentQuery query =(GetFoldersForDocumentQuery)queryRegistry.getQuery();							
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_FOLDERS_FOR_DOCUMENT(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}

	
	private AdhocQueryResponse GET_SUBMISSION_SET_AND_CONTENTS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetSubmissionSetAndContentsQuery query =(GetSubmissionSetAndContentsQuery)queryRegistry.getQuery();	
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_SUBMISSION_SET_AND_CONTENTS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	private AdhocQueryResponse GET_RELATED_DOCUMENTS(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			GetRelatedDocumentsQuery query =(GetRelatedDocumentsQuery)queryRegistry.getQuery();	
			QueryResponse queryResponse = iti18Dao_CAMEL.GET_RELATED_DOCUMENTS(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	
	private AdhocQueryResponse FIND_DOCUMENTS_BY_REFERENCE_ID(List<EbXMLRegistryError> registryError,QueryRegistry queryRegistry) {
		AdhocQueryResponse adhocQueryResponse = new AdhocQueryResponse();
		try {
			FindDocumentsByReferenceIdQuery query =(FindDocumentsByReferenceIdQuery)queryRegistry.getQuery();	
			QueryResponse queryResponse = iti18Dao_CAMEL.FIND_DOCUMENTS_BY_REFERENCE_ID(query);
			adhocQueryResponse = EbXML30Converters.convert(queryResponse);

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			genError(registryError, Severity.ERROR, ErrorCode.INVALID_REQUEST_EXCEPTION.getOpcode(),e.getMessage());
		}
		return adhocQueryResponse;
	}
	
	
	private void genError(List<EbXMLRegistryError> registryError,Severity severity,String errorCode,String codeContext) {
		EbXMLRegistryError30 re = new EbXMLRegistryError30(new RegistryError());
		re.setSeverity(severity);
		re.setErrorCode(errorCode);
		re.setCodeContext(codeContext);
		registryError.add(re);
	}
	
	public List<IheXdsFileInfo> find(String patientId) throws SQLException {
		XdsDto xdsDto = new XdsDto();
		List<IheXdsFileInfo> iheXdsInfoFileList = new ArrayList<IheXdsFileInfo>();
		IheXdsFileInfo iheXdsFileInfo =new IheXdsFileInfo();
		iheXdsFileInfo.setPatientId(patientId);
		iheXdsInfoFileList.add(iheXdsFileInfo);
		xdsDto.setIheXdsInfoList(iheXdsInfoFileList);
		DataDao dataDao = new DataDao();
		return dataDao.findFileData(xdsDto);
	}
}
